package com.xin.ui
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;

/**
 * 装箱动画实现
 * @author xin
 */
public class Texture extends Bitmap
{
	private var _source:BitmapData;
	private var _xCount:int;
	private var _yCount:int;
	
	private var _currentFrame:uint;
	private var _minFrame:uint;
	private var _maxFrame:uint;
	private var _scriptDic:Dictionary;
	private var _rect:Rectangle;
	private var _point:Point;
	
	public function Texture(source:BitmapData, xCount:int, yCount:int)
	{
		_xCount = xCount;
		_yCount = yCount;
		_source = source;
		
		_scriptDic = new Dictionary();
		
		var bmd:BitmapData = new BitmapData(source.width / xCount, source.height / yCount);
		_maxFrame = xCount * yCount;
		super(bmd);
		
		_rect = new Rectangle();
		_rect.width = this.width;
		_rect.height = this.height;
		_point = new Point();
	}
	
	private function doFrame():void
	{
		_rect.x = (_currentFrame % _xCount) * width;
		_rect.y = Math.floor(_currentFrame / _xCount) * height;
		
		this.bitmapData.copyPixels(_source, _rect, _point);
		
		var callBack:Function = _scriptDic[_currentFrame];
		if (callBack != null)
		{
			callBack();
		}
	}
	
	private function onTimer(e:TimerEvent):void
	{
		doFrame();
		
		_currentFrame ++;
		
		if (_currentFrame > _maxFrame)
		{
			_currentFrame = _minFrame;
		}
		else if (_currentFrame < _minFrame)
		{
			_currentFrame = _maxFrame;
		}
	}

	private function correctFrame() : void
	{
		_currentFrame = Math.min(_maxFrame, _currentFrame);
		_currentFrame = Math.max(_minFrame, _currentFrame);
	}
	
	public function play():void
	{
		TextureTimers.getInstance().addEventListener(TimerEvent.TIMER, onTimer);
	}
	
	public function stop():void
	{
		TextureTimers.getInstance().removeEventListener(TimerEvent.TIMER, onTimer);
	}
	
	public function gotoAndPlay(frame:uint):void
	{
		_currentFrame = frame;
		correctFrame();
		play();
	}
	
	public function gotoAndStop(frame:uint):void
	{
		_currentFrame = frame;
		correctFrame();
		doFrame();
		stop();
	}
	
	public function addFrameScript(...args):void
	{
		for (var i:int, l:int = args.length; i < l; i += 2)
		{
			var callBack:Function = args[i + 1];
			var frame:uint = args[i];
			if (callBack == null)
			{
				delete _scriptDic[frame];
			}
			else
			{
				_scriptDic[frame] = callBack;
			}
		}
	}
	
	public function setRange(minFrame:uint, maxFrame:uint):void
	{
		_minFrame = minFrame;
		_maxFrame = maxFrame;
		correctFrame();
		doFrame();
	}
	
	public function get currentFrame():uint
	{
		return _currentFrame;
	}
	
	public function get xCount():int
	{
		return _xCount;
	}
	
	public function get yCount():int
	{
		return _yCount;
	}
	
	public function get minimumFrame():uint
	{
		return _minFrame;
	}
	
	public function get maximumFrame():uint
	{
		return _maxFrame;
	}
}
}
import flash.utils.Timer;
/**
 * 随装箱动画启动的Timer单例
 */
class TextureTimers extends Timer
{
	private static var _instance:TextureTimers;
	
	/**
	 * 默认25帧/秒, 初始化即启动
	 */
	public function TextureTimers()
	{
		if (_instance == null)
		{
			super(1000 / 25);
			_instance = this;
			
			this.start();
		}
	}
	
	public static function getInstance():TextureTimers
	{
		if (_instance == null)
		{
			_instance == new TextureTimers();
		}
		return _instance;
	}
}
